feat(authz): support 'unscoped' wildcard sentinel in /v1/authz/search#303
Merged
Conversation
- Add fail-closed test: response missing both 'unscoped' and 'items' raises KeyError - Use an unambiguous truthy-non-boolean value (1) in the strict-sentinel test
danielmillerp
approved these changes
Jun 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Lets an auth provider answer
POST /v1/authz/searchwith the wildcard sentinel{ "unscoped": true }to mean all resources of this type, which the Agentex authorization proxy maps onto the existing unscoped path (None→ noid IN (...)filter) instead of an enumerated id list.adapter_agentex_authz_proxy.py): recognizeunscoped: trueand returnNone; otherwise passitemsthrough unchanged.port.py): widenlist_resourcesreturn type toIterable[str] | None.auth_provider_contract.md): formalize theunscopedsentinel in thesearchresponse schema, the inclusion-filter note, and the endpoint summary.Motivation
A provider that grants broad access (e.g. a single-account "allow everything" authorization model) previously had to enumerate every accessible id, because
items: []hides everything and there was no "all resources" signal in the contract. Enumeration couples the provider to Agentex's storage and scales poorly on large accounts. The sentinel lets such a provider answersearchstatelessly.Design notes
items: null: a provider must deliberately opt into "everything", and a malformed response missing both fields raises rather than silently failing open.AuthorizationService.list_resourcesalready returnsIterable[str] | None, and every consumer (DAuthorizedResourceIds, the list routes, the Postgres list filter) already treatsNoneas "no filter" — the path taken when authorization is disabled. The sentinel reuses that exact, already-tested path.itemsarray behave exactly as before.Test plan
tests/unit/adapters/authorization/test_adapter_agentex_authz_proxy.py):{ "items": ["a","b"] }→["a","b"]{ "unscoped": true }→None{ "unscoped": true, "items": ["x"] }→None(unscoped wins){ "items": [] }→[](sentinel not triggered; still hides everything)Greptile Summary
This PR adds an explicit wildcard response for authz search results. The main changes are:
{ "unscoped": true }from/v1/authz/searchtoNonein the authz proxy.itemsresponses as the exact inclusion filter.Confidence Score: 5/5
This looks safe to merge.
Noneas the existing no-filter path.What T-Rex did
Reviews (3): Last reviewed commit: "Merge branch 'main' into feat/authz-sear..." | Re-trigger Greptile